﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using System.IO;

namespace Tsanie.OsuDevice.Utils {
    /// <summary>
    /// 配置类
    /// </summary>
    class Config {
        public static readonly string c_AppTitle = "OsuDevice v"
            + Assembly.GetExecutingAssembly().GetName().Version.Major + "."
            + Assembly.GetExecutingAssembly().GetName().Version.Minor + "."
            + Assembly.GetExecutingAssembly().GetName().Version.Build;
        public static readonly string c_AppPath;
        private const string c_ConfigFile = "\\Tsanie.OsuDevice.xml";
        private static readonly XmlDocument _config = null;
        public const string c_Cleared = "♨";
        public const string c_Normal = "";

        static Config() {
            c_AppPath = Application.ExecutablePath.Substring(0,
                Application.ExecutablePath.LastIndexOf('\\'));
            Config.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; ) AppleWebKit/534.12 (KHTML, like Gecko) Safari/534.12 OsuDevice/"
                + Assembly.GetExecutingAssembly().GetName().Version.Major + "."
                + Assembly.GetExecutingAssembly().GetName().Version.Minor;
            Config.HttpHost = "http://osu.ppy.sh";

            if (!File.Exists(c_AppPath + c_ConfigFile)) {
                CreateConfig();
            }
            _config = new XmlDocument();
            _config.Load(c_AppPath + c_ConfigFile);
            LoadConfig();
        }
        public static void SetValue(string key, object value) {
            FieldInfo fi = typeof(Config).GetField("_" + key, BindingFlags.Static | BindingFlags.NonPublic);
            if (fi == null)
                return;
            string val = (value == null ? null : value.ToString());
            fi.SetValue(null, val);
            XmlNode node = _config.SelectSingleNode("/configuration/" + key);
            if (node == null) {
                node = _config.CreateElement(key);
                node.AppendChild(_config.CreateCDataSection(val));
                _config.SelectSingleNode("/configuration").AppendChild(node);
            } else {
                node.RemoveAll();
                node.AppendChild(_config.CreateCDataSection(val));
            }
            Save();
        }
        public static string GetValue(string key) {
            XmlNode node = _config.SelectSingleNode("/configuration/" + key);
            if (node == null)
                return null;
            string val = (string.IsNullOrEmpty(node.InnerText) ? null : node.InnerText);
            return val;
        }
        static void Save() {
            _config.Save(c_AppPath + c_ConfigFile);
        }
        public static void LoadConfig() {
            foreach (FieldInfo fi in typeof(Config).GetFields(BindingFlags.Static | BindingFlags.NonPublic)) {
                if (fi.FieldType == typeof(string) && fi.Name[0] == '_') {
                    fi.SetValue(null, GetValue(fi.Name.Substring(1)));
                }
            }
        }
        private static void CreateConfig() {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            settings.Indent = true;
            XmlWriter writer = XmlWriter.Create(c_AppPath + c_ConfigFile, settings);
            writer.WriteStartElement("configuration");
            foreach (FieldInfo fi in typeof(Config).GetFields(BindingFlags.Static | BindingFlags.NonPublic)) {
                if (fi.FieldType != typeof(string) || fi.Name[0] != '_')
                    continue;
                writer.WriteStartElement(fi.Name.Substring(1));
                object obj = fi.GetValue(null);
                writer.WriteCData(obj == null ? null : obj.ToString());
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
            writer.Flush();
            writer.Close();
        }


        public static string UserAgent { get; set; }
        public static string HttpHost { get; set; }

        public static string Cookies {
            get { return _Cookies; }
            set {
                _Cookies = value;
                //SetValue("Cookies", value);
            }
        }
        private static string _Cookies = null;
        public static int Timeout {
            get {
                int i;
                if (int.TryParse(_Timeout, out i))
                    return i;
                _Timeout = "10000";
                return 10000;
            }
            set {
                _Timeout = value.ToString();
                //SetValue("Timeout", _Timeout);
            }
        }
        private static string _Timeout = "10000";
        public static string OsuPath {
            get { return _OsuPath; }
            set {
                if (value != null && Directory.Exists(value)) {
                    _OsuPath = value;
                    //SetValue("OsuPath", value);
                }
            }
        }
        private static string _OsuPath = @"E:\Games\osu!";
        public static string GetDownloadPath(string path, bool full) {
            if (path == null || path.Length < 2)
                return path;
            if (!full) {
                if (path.ToLower().StartsWith(c_AppPath.ToLower() + "\\")) {
                    return path.Substring(c_AppPath.Length);
                }
            } else {
                if (path[1] != ':') {
                    return c_AppPath + (path[0] == '\\' ? "" : "\\") + path;
                }
            }
            return path;
        }
        public static string DownloadPath {
            get {
                if (_DownloadPath == null)
                    return null;
                return (_DownloadPath.Length > 2 && _DownloadPath[1] == ':') ? _DownloadPath : c_AppPath + _DownloadPath;
            }
            set {
                if (value == null)
                    return;
                _DownloadPath = value;
                if (_DownloadPath.ToLower().StartsWith(c_AppPath.ToLower() + "\\"))
                    _DownloadPath = _DownloadPath.Substring(c_AppPath.Length);
                //SetValue("DownloadPath", _DownloadPath);
            }
        }
        private static string _DownloadPath = "\\download";
        public static bool LogError {
            get {
                bool b;
                if (bool.TryParse(_LogError, out b))
                    return b;
                _LogError = "False";
                return false;
            }
            set {
                _LogError = value.ToString();
                //SetValue("LogError", _LogError);
            }
        }
        private static string _LogError = "False";
        public static bool TryOszSite {
            get {
                bool b;
                if (bool.TryParse(_TryOszSite, out b))
                    return b;
                _TryOszSite = "True";
                return true;
            }
            set {
                _TryOszSite = value.ToString();
                //SetValue("TryOszSite", _TryOszSite);
            }
        }
        private static string _TryOszSite = "True";
    }
}
